package com.zhome.gateway.filter.pre;

import com.google.common.util.concurrent.RateLimiter;
import com.netflix.zuul.context.RequestContext;
import com.netflix.zuul.exception.ZuulException;
import com.zhome.gateway.constants.Constants;
import com.zhome.gateway.enums.FilterEnum;
import com.zhome.gateway.enums.GateWayCodeEnum;
import com.zhome.gateway.filter.AbstractZhomeZuulFilter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;

/**
 * 限流
 * @author cuiyh9
 * @date 2020/5/9
 */
@Slf4j
public class RateLimitFilter extends AbstractZhomeZuulFilter {

    @Autowired
    private RateLimiter rateLimiter;

    @Override
    public String filterType() {
        return Constants.PRE_KEY;
    }

    @Override
    public int filterOrder() {
        return FilterEnum.RateLimitFilterEnum.getFilterOrder();
    }

    @Override
    public boolean shouldFilter() {
        RequestContext ctx = RequestContext.getCurrentContext();
        return ctx.getBoolean(Constants.RequestContextKey.CTX_X_SUCCESSOR_CAN_EXECUTE);
    }

    @Override
    public Object run() throws ZuulException {
        RequestContext ctx = RequestContext.getCurrentContext();
        if (tryAcquireTokenFail()) {
            setSkipToPostTypeFilter(ctx);
            setFailResponse(GateWayCodeEnum.REQUIRE_TOKE_FAIL);
        }
        return null;
    }

    /**
     * 获取令牌失败
     * @return boolean
     */
    private boolean tryAcquireTokenFail() {
        boolean tryAcquire = rateLimiter.tryAcquire();
        return !tryAcquire;
    }

}
